// ImageStorageManager.cpp
#include "ImageStorageManager.h"
#include <chrono>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <algorithm>

// Windows 特定头文件
#include <windows.h>
#include <sys/stat.h>

namespace fs = std::filesystem;

ImageStorageManager::ImageStorageManager()
    : is_running_(false)
    , storage_enabled_(true)
    , current_storage_size_(0)
{
}

ImageStorageManager::~ImageStorageManager()
{
    shutdown();
}

ImageStorageManager& ImageStorageManager::getInstance()
{
    static ImageStorageManager instance;
    return instance;
}

void ImageStorageManager::initialize(const std::string& base_storage_path,
                                     const DeleteRule& delete_rule,
                                     const StorageRule& storage_rule)
{
    base_storage_path_ = base_storage_path;
    delete_rule_ = delete_rule;
    storage_rule_ = storage_rule;

    // 创建基础存储目录
    if (!fs::exists(base_storage_path_)) {
        fs::create_directories(base_storage_path_);
    }

    // 计算当前存储大小
    current_storage_size_ = calculateFolderSize(base_storage_path_);

    // 启动工作线程
    is_running_ = true;
    worker_thread_ = std::thread(&ImageStorageManager::storageWorkerThread, this);
}

void ImageStorageManager::setStorageEnabled(bool enabled)
{
    storage_enabled_ = enabled;
}

void ImageStorageManager::addImage3dTask(const s_Image3dS& image_data, const std::string& name)
{
    if (!storage_enabled_) return;

    StorageTask task;
    task.type = StorageTask::STORAGE_IMAGE3D;
    task.image3d_data = image_data;
    task.name = name;

    std::lock_guard<std::mutex> lock(queue_mutex_);
    task_queue_.push(task);
    queue_condition_.notify_one();
}

void ImageStorageManager::addDefectPlateTask(const s_DefectPlateBRtsPara& defect_data, const std::string& name)
{
    if (!storage_enabled_) return;

    StorageTask task;
    task.type = StorageTask::STORAGE_DEFECT_PLATE;
    task.defect_data = defect_data;
    task.name = name;

    std::lock_guard<std::mutex> lock(queue_mutex_);
    task_queue_.push(task);
    queue_condition_.notify_one();
}

long long ImageStorageManager::getCurrentStorageSize() const
{
    return current_storage_size_;
}

int ImageStorageManager::getPendingTaskCount() const
{
    std::lock_guard<std::mutex> lock(queue_mutex_);
    return static_cast<int>(task_queue_.size());
}

void ImageStorageManager::shutdown()
{
    is_running_ = false;
    queue_condition_.notify_all();

    if (worker_thread_.joinable()) {
        worker_thread_.join();
    }
}

void ImageStorageManager::storageWorkerThread()
{
    CHVisionAdvX vision_util;  // 使用你提供的工具类

    while (is_running_) {
        StorageTask task;

        // 等待任务
        {
            std::unique_lock<std::mutex> lock(queue_mutex_);
            queue_condition_.wait(lock, [this]() {
                return !task_queue_.empty() || !is_running_;
            });

            if (!is_running_ && task_queue_.empty()) {
                break;
            }

            if (!task_queue_.empty()) {
                task = task_queue_.front();
                task_queue_.pop();
            }
        }

        if (is_running_ && storage_enabled_) {
            // 执行清理检查
            if (delete_rule_.enabled) {
                if (current_storage_size_ > delete_rule_.max_total_size) {
                    cleanupExpiredFiles();
                }
            }

            // 执行存图任务
            executeStorageTask(task);
        }
    }
}

std::string ImageStorageManager::generateTimestampFolderName()
{
    auto now = std::chrono::system_clock::now();
    auto time_t = std::chrono::system_clock::to_time_t(now);
    auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(
                            now.time_since_epoch()) % 1000;

    std::tm tm;
    localtime_s(&tm, &time_t);

    std::ostringstream oss;
    oss << std::put_time(&tm, "%Y%m%d_%H%M%S");
    oss << "_" << std::setfill('0') << std::setw(3) << milliseconds.count();

    return oss.str();
}

void ImageStorageManager::executeStorageTask(const StorageTask& task)
{
    CHVisionAdvX vision_util;

    // 根据存储模式决定文件夹路径
    std::vector<std::string> folder_paths;

    switch (storage_rule_.storage_mode) {
    case StorageRule::SINGLE_FOLDER:
        folder_paths.push_back(base_storage_path_ + "\\current");
        break;
    case StorageRule::TIMESTAMP_FOLDERS:
        folder_paths.push_back(base_storage_path_ + "\\" + generateTimestampFolderName());
        break;
    case StorageRule::BOTH_MODES:
        folder_paths.push_back(base_storage_path_ + "\\current");
        folder_paths.push_back(base_storage_path_ + "\\" + generateTimestampFolderName());
        break;
    }

    try {
        for (const auto& folder_path : folder_paths) {
            // 确保文件夹存在
            if (!fs::exists(folder_path)) {
                fs::create_directories(folder_path);
            }

            switch (task.type) {
            case StorageTask::STORAGE_IMAGE3D:
                vision_util.WriteImage3DX(task.image3d_data, folder_path, task.name);
                break;
            case StorageTask::STORAGE_DEFECT_PLATE:
                vision_util.WriteDefectPlateBRtsImage(task.defect_data, folder_path, task.name);
                break;
            }
        }

        // 更新存储大小
        current_storage_size_ = calculateFolderSize(base_storage_path_);

    } catch (const std::exception& e) {
        // 记录错误日志（在实际项目中应该使用日志库）
        // std::cerr << "Storage task failed: " << e.what() << std::endl;
    }
}

void ImageStorageManager::cleanupExpiredFiles()
{
    auto current_time = std::chrono::system_clock::now();

    for (const auto& entry : fs::directory_iterator(base_storage_path_)) {
        if (!entry.is_directory()) continue;

        try {
            // 使用传统方法获取文件时间信息
            std::string folder_path = entry.path().string();

            struct _stat file_stat;
            if (_stat(folder_path.c_str(), &file_stat) != 0) {
                continue; // 无法获取文件状态，跳过
            }

            // 将文件修改时间转换为 time_point
            auto file_time = std::chrono::system_clock::from_time_t(file_stat.st_mtime);

            // 计算时间差
            auto duration = current_time - file_time;
            auto hours = std::chrono::duration_cast<std::chrono::hours>(duration);

            int days = static_cast<int>(hours.count() / 24);

            if (days > delete_rule_.max_days) {
                long long folder_size = calculateFolderSize(folder_path);
                if (deleteFolder(folder_path)) {
                    current_storage_size_ -= folder_size;
                }
            }
        } catch (const std::exception& e) {
            // 记录错误日志
            continue;
        }
    }
}

long long ImageStorageManager::calculateFolderSize(const std::string& folder_path)
{
    long long total_size = 0;

    try {
        for (const auto& entry : fs::recursive_directory_iterator(folder_path)) {
            if (entry.is_regular_file()) {
                total_size += entry.file_size();
            }
        }
    } catch (const std::exception& e) {
        // 记录错误日志
    }

    return total_size;
}

bool ImageStorageManager::deleteFolder(const std::string& folder_path)
{
    try {
        fs::remove_all(folder_path);
        return true;
    } catch (const std::exception& e) {
        // 记录错误日志
        return false;
    }
}
